package com.gcxx.framework.security.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.springframework.context.ApplicationContext;

import com.gcxx.framework.base.dao.BaseDAO;
import com.gcxx.framework.base.entity.PageBean;
import com.gcxx.framework.security.dao.IFrsfGroupDAO;
import com.gcxx.framework.security.entity.FrsfGroup;
import com.gcxx.framework.security.entity.FrsfGroupRole;
import com.gcxx.framework.security.entity.FrsfOrg;
import com.gcxx.framework.security.entity.FrsfRole;
import com.gcxx.framework.security.entity.FrsfUser;
import com.gcxx.framework.security.entity.FrsfUserGroup;
import com.gcxx.framework.util.string.StringUtil;

/**
 * A data access object (DAO) providing persistence and search support for
 * FrsfGroup entities. Transaction control of the save(), update() and delete()
 * operations can directly support Spring container-managed transactions or they
 * can be augmented to handle user-managed Spring transactions. Each of these
 * methods provides additional information for how to configure it for the
 * desired type of transaction control.
 * 
 * @see com.gcxx.framework.security.dao.FrsfGroup
 * @author MyEclipse Persistence Tools
 */

public class FrsfGroupDAO extends BaseDAO implements IFrsfGroupDAO {
	private static final Log log = LogFactory.getLog(FrsfGroupDAO.class);

	protected void initDao() {
		// do nothing
	}

	public void save(FrsfGroup transientInstance) {
		log.debug("saving FrsfGroup instance");
		try {
			getHibernateTemplate().save(transientInstance);
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

	public void delete(FrsfGroup persistentInstance) {
		log.debug("deleting FrsfGroup instance");
		try {
			getHibernateTemplate().delete(persistentInstance);
			//级联删除群组权限关系表(frsf_group_role)
			Map map = new HashMap();
			map.put("groupId", persistentInstance.getId());
			String Hql1= "delete from " + FrsfGroupRole.class.getName() + " where  groupId= :groupId";
			execute(Hql1, map);
			//级联删除用户群组关系表(frsf_user_group)
			String Hql2= "delete from " + FrsfUserGroup.class.getName() + " where  groupId= :groupId";
			execute(Hql2, map);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	public FrsfGroup findById(java.lang.String id) {
		log.debug("getting FrsfGroup instance with id: " + id);
		try {
//			FrsfGroup instance = (FrsfGroup) getHibernateTemplate().get(
//					"com.gcxx.framework.security.dao.FrsfGroup", id);
//			return instance;
			Map map = new HashMap();
			map.put("id", id);
			String Hql= "from " + FrsfGroup.class.getName() + " where  id= :id";
		  
			List result = findByHQLMap(Hql, map);
			FrsfGroup instance =(FrsfGroup)result.get(0);
			//取得该群组下的所有用户
			if(StringUtil.isNotNull(id)){
				StringBuffer hql=new StringBuffer();
				Map<String, String > map2 = new HashMap();
				map2.put("id", id);
				hql.append(" select distinct(a) "
						 + " from " + FrsfUser.class.getName() + " a, "+ FrsfUserGroup.class.getName() + " b, " + FrsfGroup.class.getName() + " c "
						 + " where b.groupId = c.id "
						 + " and b.userId = a.id "
						 + " and a.state = 1 "
						 + " and c.id =:id " );
				List<FrsfUser> users = findByHQLMap(hql.toString(), map);
				if(users != null && !users.isEmpty()){
					instance.setUsers(users);
				}
			}
			//取得该群组下的所有权限集合
			if(StringUtil.isNotNull(id)){
				StringBuffer hql=new StringBuffer();
				Map<String, String > map2 = new HashMap();
				map2.put("id", id);
				hql.append(" select distinct(a) "
						 + " from " + FrsfRole.class.getName() + " a, "+ FrsfGroupRole.class.getName() + " b, " + FrsfGroup.class.getName() + " c "
						 + " where b.groupId = c.id "
						 + " and b.roleId = a.id "
						 + " and c.id =:id " );
				List<FrsfRole> roles = findByHQLMap(hql.toString(), map);
				if(roles != null && !roles.isEmpty()){
					instance.setRoles(roles);
				}
			}
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	public List findByExample(FrsfGroup instance) {
		log.debug("finding FrsfGroup instance by example");
		try {
			List results = getHibernateTemplate().findByExample(instance);
			log.debug("find by example successful, result size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	public List findByProperty(String propertyName, Object value) {
		log.debug("finding FrsfGroup instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from FrsfGroup as model where model."
					+ propertyName + "= ?";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	public List findAll() {
		log.debug("finding all FrsfGroup instances");
		try {
			String queryString = "from FrsfGroup";
			return getHibernateTemplate().find(queryString);
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

	public FrsfGroup merge(FrsfGroup detachedInstance) {
		log.debug("merging FrsfGroup instance");
		try {
			FrsfGroup result = (FrsfGroup) getHibernateTemplate().merge(
					detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public void attachDirty(FrsfGroup instance) {
		log.debug("attaching dirty FrsfGroup instance");
		try {
			getHibernateTemplate().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void attachClean(FrsfGroup instance) {
		log.debug("attaching clean FrsfGroup instance");
		try {
			getHibernateTemplate().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}
	
	/* (non-Javadoc)
	 * @see com.gcxx.framework.security.dao.IFrsfGroupDAO#getGroupsByUserID(java.lang.String)
	 */
	public List<FrsfGroup> getGroupsByUserID(String userID) {
		log.debug("getGroupsByUserID FrsfGroup with property userID:" + userID);
		if(StringUtil.isNotNull(userID)){
			try {
				StringBuffer hql=new StringBuffer();
				Map<String, String > map = new HashMap<String, String>();
				hql.append("select distinct(a) "
						 + "from " + FrsfGroup.class.getName() + " a, "+ FrsfUserGroup.class.getName() +" b "
						 + "where a.id = b.groupId "
						 + "and b.userId =:userID " );
				map.put("userID", userID);
				List<FrsfGroup> result = findByHQLMap(hql.toString(), map);
				if(result != null && !result.isEmpty()){
					return result;
				}
				
				log.debug("getGroupsByUserID successful");
			} catch (RuntimeException re) {
				log.error("getGroupsByUserID failed", re);
				throw re;
			}
		}
		return null;
	}
	
	/* (non-Javadoc)
	 * @see com.gcxx.framework.security.dao.IFrsfGroupDAO#findByCondition(java.util.Map, java.lang.String[], int, int)
	 */
	public Map findByCondition( Map condition, String[] order,int index,int pageSize) {
		StringBuffer hql = new StringBuffer();
		hql.append("select count(*) from " + FrsfGroup.class.getName() + " where 1=1 ");
		Map map = new HashMap();
		Map resultMap=new HashMap();
		if(condition != null && !condition.isEmpty()){
			if(condition.get("groupName") != null){
				map.put("groupName", "%" + condition.get("groupName") + "%");
				hql.append("and groupName like :groupName ");
			}
		}
		
		/*if(order != null && order.length > 0){
			hql.append("order by ");
			for (int i = 0; i < order.length; i++) {
				hql.append(" " +order[i]);
				if(i < order.length - 1){
					hql.append(",");
				}
			}
		}*/

		List result = null;
		int totalSize=0;
		String queryHql = hql.substring(16);
		int pageNo=(index/pageSize)+1;
		result=this.findPageByQuery(pageNo,pageSize,queryHql, map);
		totalSize=this.getTotalCount(hql.toString(), map);

		resultMap.put("result", result);
		resultMap.put("totalSize", totalSize);
		return resultMap;
	}
	
	
	
	/* (non-Javadoc)
	 * @see com.gcxx.framework.security.dao.IFrsfGroupDAO#findFlowRoleByCondition(java.util.Map, java.lang.String[], int, int,String)
	 */
	public Map findFlowRoleByCondition( Map condition, String[] order,int index,int pageSize,String groupId) {
		StringBuffer hql = new StringBuffer();
		StringBuffer hql2 = new StringBuffer();
		//取得该群组下的所有用户信息
		Map map = new HashMap();
		Map resultMap=new HashMap();
		if(StringUtil.isNotNull(groupId)){
			map.put("id", groupId);
			hql.append(" select count(*) from " + FrsfUser.class.getName() + " a, "+ FrsfUserGroup.class.getName() + " b, " + FrsfOrg.class.getName() + " c "
					 + " where a.id = b.userId "
					 + " and b.groupId = :id "
					 + " and a.state = 1 "
					 + " and a.orgID = c.id " );
			
			if(condition != null && !condition.isEmpty()){
				if(condition.get("orgId") != null && !"".equals(condition.get("orgId"))){
					map.put("orgId", condition.get("orgId") );
					hql.append("and a.orgID =:orgId ");
				}
				if(condition.get("userName") != null && !"".equals(condition.get("userName"))){
					map.put("userName", "%" + condition.get("userName") + "%");
					hql.append("and a.empName like :userName ");
				}
			}
			
			if(order != null && order.length > 0){
				hql.append("order by ");
				for (int i = 0; i < order.length; i++) {
					hql.append(" " +order[i]);
					if(i < order.length - 1){
						hql.append(",");
					}
				}
			}
			
			List result = null;
			int totalSize=0;
			String queryHql = hql.substring(16);
			int pageNo=(index/pageSize)+1;
			result=this.findPageByQuery(pageNo,pageSize,queryHql, map);
			totalSize=this.getTotalCount(hql.toString(), map);
			resultMap.put("result", result);
			resultMap.put("totalSize", totalSize);
		}

		return resultMap;
	}
	
	
	/* (non-Javadoc)
	 * @see com.gcxx.framework.security.dao.IFrsfGroupDAO#findNotInGroupUsers(java.util.Map, java.lang.String[], int, int)
	 */
	public Map findNotInGroupUsers( Map condition, String[] order,int index,int pageSize) {
		StringBuffer hql = new StringBuffer();
		StringBuffer hql2 = new StringBuffer();
		//取得该群组以外的系统用户信息
		Map map = new HashMap();
		Map resultMap=new HashMap();
		hql.append(" select count(*) from " + FrsfUser.class.getName() + " a," + FrsfOrg.class.getName() + " b "
				 + " where 1=1  "
				 + " and a.state = 1 "
				 + " and a.orgID = b.id " );
		
		if(condition != null && !condition.isEmpty()){
			if(condition.get("userList") != null && !"".equals(condition.get("userList"))){
				map.put("userList", condition.get("userList") );
				hql.append(" and a.id not in ( :userList ) ");
			}
			if(condition.get("orgId") != null && !"".equals(condition.get("orgId"))){
				map.put("orgId", condition.get("orgId") );
				hql.append(" and a.orgID =:orgId ");
			}
			if(condition.get("userName") != null && !"".equals(condition.get("userName"))){
				map.put("userName", "%" + condition.get("userName") + "%");
				hql.append(" and a.empName like :userName ");
			}
		}
		
		if(order != null && order.length > 0){
			hql.append("order by ");
			for (int i = 0; i < order.length; i++) {
				hql.append(" " +order[i]);
				if(i < order.length - 1){
					hql.append(",");
				}
			}
		}
		
		List result = null;
		int totalSize=0;
		String queryHql = hql.substring(16);
		int pageNo=(index/pageSize)+1;
		result=this.findPageByQuery(pageNo,pageSize,queryHql, map);
		totalSize=this.getTotalCount(hql.toString(), map);
		resultMap.put("result", result);
		resultMap.put("totalSize", totalSize);

		return resultMap;
	}
	
	/* (non-Javadoc)
	 * @see com.gcxx.framework.security.dao.IFrsfGroupDAO#deleteByIds(java.util.List)
	 */
	public void deleteByIds(List<FrsfGroup> entitys){
		log.debug("deleteByIds");
		try {
			if(entitys != null && !entitys.isEmpty()){
				for (FrsfGroup frsfGroup : entitys) {				
					getHibernateTemplate().deleteAll(entitys);
					//级联删除群组权限关系表(frsf_group_role)
					Map map = new HashMap();
					map.put("groupId", frsfGroup.getId());
					String Hql1= "delete from " + FrsfGroupRole.class.getName() + " where  groupId= :groupId";
					execute(Hql1, map);
					//级联删除用户群组关系表(frsf_user_group)
					String Hql2= "delete from " + FrsfUserGroup.class.getName() + " where  groupId= :groupId";
					execute(Hql2, map);
				}
			}
			log.debug("deleteByIds successful");
		} catch (RuntimeException re) {
			log.error("deleteByIds failed", re);
			throw re;
		}
	}
	
	/* (non-Javadoc)
	 * @see com.gcxx.framework.security.dao.IFrsfGroupDAO#findNameByNId(com.gcxx.framework.security.entity.FrsfGroup)
	 */
	public List<FrsfGroup>  findNameByNId(FrsfGroup entity){
		Map map = new HashMap();
		map.put("id", entity.getId());
		map.put("groupName", entity.getGroupName());
		String Hql= "from " + FrsfGroup.class.getName() + " where  id<> :id and groupName=:groupName"; 
		List<FrsfGroup> result = findByHQLMap(Hql, map);
		return result;
	}
	
	
	public static FrsfGroupDAO getFromApplicationContext(ApplicationContext ctx) {
		return (FrsfGroupDAO) ctx.getBean("FrsfGroupDAO");
	}

	@Override
	public PageBean findByConditionForHospital(PageBean page) {
		Map<String, String> condition = page.getCondition();
		int index = page.getPageNo();
		int pageSize = page.getPageSize();
		StringBuffer sql = new StringBuffer();
		StringBuffer selectSql = new StringBuffer();
		
		sql.append(" FROM FRSF_GROUP A " +
				 " WHERE 1=1  ");
		
		selectSql.append("SELECT A.ID, A.GROUP_NAME, A.GROUP_DESC  ");

		if(condition !=null && condition.size()>0) {
			
			if(StringUtil.isNotNull(condition.get("groupName"))){
				condition.put("groupName", "%" + condition.get("groupName") + "%");
				sql.append(" AND A.GROUP_NAME LIKE :groupName ");
			}
			
			
		}
		
		sql.append(" ORDER BY A.GROUP_NAME");
		
		List<Object> result = null;
		int totalSize=0;
		//记录总数
		totalSize=this.getTotalCountBySQL("select count(*)" + sql.toString(), condition);
		
		//当页记录
		result=this.findPageBySQLQuery(page.getPageNoIsRowNumber() ? getPageIndex(index,pageSize) : index,pageSize,selectSql.toString() + sql.toString(), condition, FrsfGroup.class);

		page.setResultList(result);
		page.setRowCount(totalSize);
		
		return page;
	}
}